'''
Created on 07-02-2012

@author: cleve
'''

import math
import numpy
import os
from operator import itemgetter


class FilesClass(object):
    '''
    classdocs
    '''


    def __init__(self, ruta):
        '''
        Constructor
        '''
        self.ruta = ruta
        
        #Cargo archivo en memoria
        self.matrizDistancia, self.tipoProblema = self.Carga_archivo(self.ruta)
    
    def CargarTSP(self, rutaArchivo):
        f = open(rutaArchivo, 'r')
            
        line = f.readline()
        while line.find("EDGE_WEIGHT_TYPE") == -1:
            line = f.readline()
        
        if line.find("EUC_2D") != -1:
            pass
        elif line.find("MAN_2D") != -1:
            pass
        else:
            print ("Only Euclidean distance.")
            raise Exception
        
        while line.find("NODE_COORD_SECTION") == -1:
            line = f.readline()
        
        xy_positions = []
            
        while 1:
            line = f.readline()
            if line.find("EOF") != -1: break
            (i, x, y) = line.split()
            x = float(x)
            y = float(y)
            xy_positions.append((x, y))
        
        f.close()
            
        D = self.Construye_matriz_distancia(xy_positions)
        
        return D, 'tsp'
    
    def CargarMochila(self, rutaArchivo):
        f = open(rutaArchivo, 'r')
            
        line = f.readline()
        while line.find("MC") == -1:
            line = f.readline()
    
        #Obtengo peso desde archivo ".m"
        maxWeight = float(line.split('=')[1])
    
        while line.find("ELEMENT,WEIGHT, UTILITY") == -1:
            line = f.readline()
    
        #listaUtilidades = []
        #listaPesos = []
        self.listaElementos = []
        
        while 1:
            line = f.readline()
            if line.find("EOF") != -1: break
            (i, w, u) = line.split(',')
            
            #Lista con (pesos, utilidades, identificador)
            self.listaElementos.append((float(w), float(u), int(i)))
        
        f.close()
        
        #Creo matriz con pesos
        
        self.maxWeight = maxWeight
        #self.listaUtilidades = listaUtilidades
        
        return 'md', 'kp' 

    
    def GetListaElementos(self):
        return self.listaElementos
    
    
    def GetMaximaCapacidad(self):
        return self.maxWeight
    
    def GetMatrizDistancia(self):
        return numpy.array(self.matrizDistancia)
    
    def GetTipoProblema(self):
        return self.tipoProblema    
    
    def Calcula_distancia(self, (x1, y1), (x2, y2)):
        """Calcula distancia euclidiana"""
        
        xd = x2 - x1
        yd = y2 - y1
        
        return float(math.sqrt(xd * xd + yd * yd))
  
    def Construye_matriz_distancia(self, coord):
        """hace matriz de distancia con las coordenadas
        pasadas
            """
        n = len(coord)
            
        D = [[0 for i in range(n)] for i in range(n)]      # lista
            
        for i in xrange(n - 1):
            for j in xrange(i + 1, n):
                
                (x1, y1) = coord[i]
                (x2, y2) = coord[j]
                D[i][j] = self.Calcula_distancia((x1, y1), (x2, y2))
                D[j][i] = D[i][j]
          
        return D
      
    def Carga_archivo(self, rutaArchivo):
        """ Creacion de matriz
      
        @param ruta_archivo: Ruta de archivo TSPLIB o m (mochila)
        @return none: self.nodos nodos y self.grafo Matriz de distancia del grafo de entrada.
        """
        
        #Obtengo nombte de archivo y extension de entrada.
        fileName, fileExtension = os.path.splitext(rutaArchivo)
        
        if fileExtension == '.tsp':
            return self.CargarTSP(rutaArchivo)
        
        elif fileExtension == '.kp':
            return self.CargarMochila(rutaArchivo)
            